
#pragma once


#include <sstream>

#if defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW__)
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Weffc++"
    #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#endif


namespace tools{
    namespace variant_detail{

        template<class U> struct Helper: IHelper
        {
            typedef typename variant_detail::PropertyType<U>::Type Type;
            enum { eMYTYPE     = Type2Enum<Type>::eTYPE };
            enum { eMYCATEGORY = Enum2Category<eMYTYPE>::eCATEGORY };
            typedef TargetIterator<U, eMYCATEGORY>  Rule;

            virtual bool IsValueSame(const void* my, const void* other)const
            {
                return HelperCompare<U>::IsValueSame( my, other );
            }

            virtual bool IsTypeSame(const eTYPE& type)const 
            {
                return static_cast<eTYPE>(eMYTYPE)==type;
            }

            virtual size_t GetSize()const   { return sizeof(U); }
            virtual bool IsPrimitive()const { return static_cast<eCATEGORY>(eMYCATEGORY)==ePRIMITIVE; }
            virtual bool IsFloating()const  { return PropertyType<U>::eIS_FLOAT == 1; }
            virtual bool IsInteger()const   { return PropertyType<U>::eIS_INT   == 1; }

            virtual const ::std::type_info& GetTypeInfo()const  { return typeid(U); }

            virtual const char* GetTypeName()const { return Enum2Name<eMYTYPE>::Name();          }
            virtual eTYPE GetType()const           { return static_cast<eTYPE>(eMYTYPE);         }
            virtual eCATEGORY GetCategory()const   { return static_cast<eCATEGORY>(eMYCATEGORY); }

            virtual size_t Elements(const void* const data)const { return GetElements<U>::Elements(data); }
            
            virtual const Str ToString(const void* const data)const
            {
                ::std::stringstream ss;
                Out<U>::ToString(data,ss);
                return ss.str();
            }
    //-------------------------------------------------------------------------
            virtual Native GetIterator(Variant& variant,const bool beg)const
            {
                return Rule::GetIterator(variant,beg);
            }
            virtual Native GetConstIterator(const Variant& variant, const bool beg)const
            {
                return Rule::GetConstIterator(variant,beg);
            }
            virtual Native GetConstIterator(Variant& variant, const bool beg)const
            {
                return Rule::GetConstIterator(variant,beg);
            }
            virtual Native GetReverseIterator(Variant& variant, const bool beg)const
            {
                return Rule::GetReverseIterator(variant,beg);
            }
            virtual Native GetConstReverseIterator(const Variant& variant, const bool beg)const
            {
                return Rule::GetConstReverseIterator(variant,beg);
            }
            virtual Native GetConstReverseIterator(Variant& variant, const bool beg)const
            {
                return Rule::GetConstReverseIterator(variant,beg);
            }
    //-------------------------------------------------------------------------
            virtual Native GetPrimitiveIterator(Variant& variant,const bool beg)const
            {
                return Rule::GetPrimitiveIterator(variant,beg);
            }
            virtual Native GetPrimitiveConstIterator(const Variant& variant,const bool beg)const
            {
                return Rule::GetPrimitiveConstIterator(variant,beg);
            }
            virtual Native GetPrimitiveConstIterator(Variant& variant,const bool beg)const
            {
                return Rule::GetPrimitiveConstIterator(variant,beg);
            }
            virtual Native GetPrimitiveReverseIterator(Variant& variant,const bool beg)const
            {
                return Rule::GetPrimitiveReverseIterator(variant,beg);
            }
            virtual Native GetPrimitiveConstReverseIterator(const Variant& variant,const bool beg)const
            {
                return Rule::GetPrimitiveConstReverseIterator(variant,beg);
            }
            virtual Native GetPrimitiveConstReverseIterator(Variant& variant,const bool beg)const
            {
                return Rule::GetPrimitiveConstReverseIterator(variant,beg);
            }
    //-------------------------------------------------------------------------

//        private:
//            friend class boost::serialization::access;

//            template<class Archive>
//            void serialize(Archive & ar, const unsigned int )
//            {
//                //const bool ERROR_SERIALIZATION_EMPTY_DATA

//                //auto& var   = GetOwner();
//                //auto& data  = var.GetData();
//                //auto& value = data.Cast<U>();


//                //arch << BOOST_SERIALIZATION_NVP(mType);

//                auto& value = GetOwner().Cast<U>();

//                ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(IHelper);
//                ar & BOOST_SERIALIZATION_NVP(value);
//            }

        };



    }//namespace variant_detail
}//namespace tools


#if defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW__)
    #pragma GCC diagnostic pop
#endif
